package plsqlfs;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.junit.Assert;

import com.google.common.io.ByteStreams;

public class FtpRemoteFileSystem implements RemoteFileSystem {

	private final FTPClient ftpClient;

	public FtpRemoteFileSystem(FTPClient ftpClient) {
		this.ftpClient = ftpClient;
	}

	public void changeWorkingDirectory(String directory) throws IOException {
		if (!ftpClient.changeWorkingDirectory(directory)) {
			throw new IOException("Could not change working directory to " + directory);
		}
	}

	public void createFile(String fileName) throws IOException {
		if (!ftpClient.storeFile(fileName, new ByteArrayInputStream(new byte[0]))) {
			throw new IOException("Could not create file " + fileName);
		}
	}

	public void createFile(String fileName, InputStream fileContent) throws IOException {
		byte[] contentBytes = ByteStreams.toByteArray(fileContent);
		
		if (!ftpClient.storeFile(fileName, new ByteArrayInputStream(contentBytes))) {
			throw new IOException("Could not create file " + fileName);
		}
		
		Assert.assertTrue("File was not created", fileExists(fileName));
		Assert.assertArrayEquals("File content is not correct", contentBytes, retrieveFileBytes(fileName));
	}

	public boolean fileExists(String name) throws IOException {
		FTPFile[] names;
		
		int count = 0;
		
		do {
			names = ftpClient.listFiles();
			if (names == null) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {
				break;
			}
			
			count++;
		} while (count < 3);
		
		if (names == null) {
			throw new IOException("Unable to list files");
		}
		
		for (FTPFile file : names) {
			System.err.println(file.getName());
			if (name.equals(file.getName())) {
				return true;
			}
		}
		return false;
	}

	public void createDirectory(String directoryName) throws IOException {
		// TODO Auto-generated method stub
		if (!ftpClient.makeDirectory(directoryName)) {
			//throw new IOException("Could not create directory " + directoryName + " within parent directory " + directory);
			System.err.println("Warning: Could not create directory " + directoryName);
		}
	}

	public void deleteFile(String fileName) throws IOException {
		if (!ftpClient.deleteFile(fileName)) {
			System.err.println("Warning: Could not delete file " + fileName);
		}
	}

	public InputStream retrieveFileStream(String name) throws IOException {
		return ftpClient.retrieveFileStream(name);
	}

	public byte[] retrieveFileBytes(String name) throws IOException {
		return ByteStreams.toByteArray(retrieveFileStream(name));
	}

}
